﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using StockControl;
using StockLib;

namespace StockUI
{
    public partial class FormReport : FormAbstractChild
    {
        private StockGridControl gridReport;

        private string currentBlockId = string.Empty;

        private Dictionary<string, ContextMenuStrip> groupMenu = new Dictionary<string, ContextMenuStrip>();

        public FormReport()
        {
            InitializeComponent();

            gridReport = new StockGridControl();
            gridReport.Margin = new Padding(5, 3, 5, 0);
            gridReport.Dock = DockStyle.Fill;
            gridReport.Leave += new EventHandler(gridReport_Leave);
            gridReport.CellDoubleClick += new DataGridViewCellEventHandler(gridReport_CellDoubleClick);
            gridReport.CellMouseClick += new DataGridViewCellMouseEventHandler(gridReport_CellMouseClick);
            gridReport.SortNeeded += new StockGridControlSortNeededHandler(gridReport_SortNeeded);
            pnlReport.Controls.Add(gridReport, 0, 0);

            //订阅股票数据更改事件
            StockContainer.Instance.DataChanged += new StockContainerDataEventHandler(StockContainer_DataChanged);

            //订阅板块数据更改事件
            StockBlockGroupCustom.Instance.DataChanged += new StockBlockGroupDataEventHandler(StockBlockGroupCustom_DataChanged);
            StockBlockGroupCustom.Instance.StockDataChanged += new StockBlockGroupStockDataEventHandler(StockBlockGroupCustom_StockDataChanged);

            //订阅标签数据更改事件
            StockTabContainer.Instance.DataChanged += new StockTabContainerDataEventHandler(StockTabContainer_DataChanged);
        }
        protected void FormReport_Load(object sender, EventArgs e)
        {
            //创建板块列表菜单
            CreateAllGroupMenu();

            //显示缺省标签
            BlockTabDataRefresh();
            BlockTabSelectFirst();

            gridReport.Select();
        }

        //股票容器数据更改时，更新列表显示
        private void StockContainer_DataChanged(object sender, EventArgs e)
        {
            BlockStockDataRefrech();
        }

        //板块容器数据更改时，更新标签显示
        private void StockBlockGroupCustom_DataChanged(object sender, EventArgs e)
        {
            BlockDataRefrech();
        }

        //板块容器股票数据更改时，更新标签显示
        private void StockBlockGroupCustom_StockDataChanged(object sender, EventArgs e)
        {
            if (currentBlockId.StartsWith(StockBlockGroupCustom.BLOCK_GROUP_ID) && Regex.IsMatch(currentBlockId, @"^(.+)\.(.+)$"))
            {
                BlockStockDataRefrech();
            }
        }

        //标签容器数据更改时，更新标签显示
        private void StockTabContainer_DataChanged(object sender, EventArgs e)
        {
            BlockTabDataRefresh();
        }

        private void FormReport_Enter(object sender, EventArgs e)
        {
            gridReport.Select();
        }

        private void FormReport_Resize(object sender, EventArgs e)
        {
            BlockTabFit();
        }

        private void gridReport_Leave(object sender, EventArgs e)
        {
            if (this.IsActive)
                gridReport.Select();
        }

        private void gridReport_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            {
                SendKeys.Send("{ENTER}");
            }
        }

        private void gridReport_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right && e.RowIndex >= 0 && e.ColumnIndex >= 0)
            {
                PopupOperationMenu();
            }
        }

        private void gridReport_SortNeeded(object sender, EventArgs e)
        {
            BlockStockDataRefrech();
        }

        private int FindTabIndex(Point location)
        {
            int clickIndex = -1;
            for (int i = 0; i < tabReport.TabCount; i++)
            {
                if (tabReport.GetTabRect(i).Contains(location))
                {
                    clickIndex = i;
                }
            }

            return clickIndex;
        }

        private void tabReport_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && e.Clicks == 1)
            {
                PopupGroupMenu(FindTabIndex(e.Location));
            }
        }

        bool suppressSelectingWhenIndexChanged = false;
        private void tabReport_SelectedIndexChanged(object sender, EventArgs e)
        {
            string blockId = Convert.ToString(tabReport.SelectedTab.Tag);
            string blockLabel = Convert.ToString(tabReport.SelectedTab.Text);
            if (!suppressSelectingWhenIndexChanged && !BlockIsGroup(blockId))
            {
                BlockSwitch(blockLabel, blockId);
            }
        }

        bool suppressSwitchWhentIndexChanging = true;
        private void tabReport_Selecting(object sender, TabControlCancelEventArgs e)
        {
            string blockId = Convert.ToString(e.TabPage.Tag);
            if (BlockIsGroup(blockId) && suppressSwitchWhentIndexChanging)
            {
                e.Cancel = true;
            }
        }

        private void cmdGroupMenuItem_Click(object sender, EventArgs e)
        {
            if (!(sender is ToolStripMenuItem))
                return;

            ToolStripMenuItem menu = sender as ToolStripMenuItem;
            if (Convert.ToString(menu.Tag) != currentBlockId)
            {
                BlockSwitch(menu.Text, Convert.ToString(menu.Tag));
            }
        }

        //显示操作菜单
        private void PopupOperationMenu()
        {
            ToolStripDropDownDirection direction = ToolStripDropDownDirection.Default;
            if (MousePosition.Y > gridReport.Bottom - menuOperation.Height)
            {
                direction = (MousePosition.X > gridReport.Right - menuOperation.Width) ? ToolStripDropDownDirection.AboveLeft : ToolStripDropDownDirection.AboveRight;
            }
            else
            {
                direction = (MousePosition.X > gridReport.Right - menuOperation.Width) ? ToolStripDropDownDirection.BelowLeft : ToolStripDropDownDirection.BelowRight;
            }

            menuOperation.DefaultDropDownDirection = ToolStripDropDownDirection.AboveLeft;
            menuOperation.Show(MousePosition, direction);

            cmdBlockDelete.Enabled = StockBlockGroupCustom.Instance.ContainsKey(currentBlockId);
        }

        //在分组标签上显示菜单
        private bool PopupGroupMenu(int tabIndex)
        {
            if (tabIndex < 0)
                return false;

            bool popup = false;
            TabPage page = tabReport.TabPages[tabIndex];
            string blockId = Convert.ToString(page.Tag);
            if (BlockIsGroup(blockId))
            {
                popup = true;

                ContextMenuStrip menu = groupMenu[blockId];
                menu.Tag = page;
                menu.Show(tabReport, tabReport.GetTabRect(tabIndex).Location, ToolStripDropDownDirection.AboveRight);

                foreach (ToolStripItem mi in menu.Items)
                {
                    if (!(mi is ToolStripMenuItem))
                        continue;

                    string blockIdItem = Convert.ToString(mi.Tag);
                    (mi as ToolStripMenuItem).Checked = (currentBlockId == blockIdItem);
                }
            }

            return popup;
        }

        private void picTabAdd_Click(object sender, EventArgs e)
        {
            new DialogOptionTab().ShowDialog(this);
        }

        //设置合适宽度
        private void BlockTabFit()
        {
            int width = 10;
            for (int i = 0; i < tabReport.TabCount; i++)
            {
                if (width < ClientSize.Width - 300)
                {
                    width += tabReport.GetTabRect(i).Width;
                }
            }
            if (width < ClientSize.Width - 300)
            {
                tabReport.Width = width;
            }
            else
            {
                tabReport.Width = ClientSize.Width - 300;
            }
        }

        // 创建所有分类菜单
        private void CreateAllGroupMenu()
        {
            CreateGroupMenu(StockBlockGroupClass.BLOCK_GROUP_ID);
            foreach (string blockClass in StockBlockGroupRegular.Instance.Groups)
            {
                string blockId = blockClass + ".";
                CreateGroupMenu(blockId);
            }
            CreateGroupMenu(StockBlockGroupCustom.BLOCK_GROUP_ID);
        }

        //创建分类列表菜单
        private void CreateGroupMenu(string blockId)
        {
            ContextMenuStrip menu = null;
            bool exist = groupMenu.ContainsKey(blockId);
            if (exist)
            {
                menu = groupMenu[blockId];
            }
            else
            {
                menu = new ContextMenuStrip();
                groupMenu.Add(blockId, menu);
            }

            // 板块菜单需要重建，其他预定义菜单只有初始化的时候需要创建
            if (!exist || blockId == StockBlockGroupCustom.BLOCK_GROUP_ID)
            {
                IEnumerable blockList = null;
                switch (blockId)
                {
                    case StockBlockGroupClass.BLOCK_GROUP_ID:
                        blockList = StockBlockGroupClass.Instance.Values;
                        break;

                    case StockBlockGroupCustom.BLOCK_GROUP_ID:
                        blockList = StockBlockGroupCustom.Instance.Values.Where(d => (d.BlockId != StockBlockGroupCustom.Instance.ZXGBlock.BlockId));
                        break;

                    default:
                        blockList = StockBlockGroupRegular.Instance.Values.Where(d => d.GroupId == blockId);
                        break;
                }
                if (blockList == null)
                    return;

                menu.Items.Clear();
                foreach (StockBlock block in blockList)
                {
                    ToolStripMenuItem item = new ToolStripMenuItem(block.Name);
                    item.Tag = block.BlockId;
                    item.Click += cmdGroupMenuItem_Click;
                    menu.Items.Add(item);
                }
            }
        }

        //创建行情表情
        private TabPage CreateReportTab(string blockLabel, string blockId, int index)
        {
            TabPage page = null;
            if (string.IsNullOrEmpty(blockId))
                return null;

            //如果是分组，在标签旁边增加箭头
            if (BlockIsGroup(blockId))
            {
                blockLabel += " ▲";
            }

            page = new TabPage(blockLabel);
            page.BackColor = Color.Black;
            page.Tag = blockId;
            if (index < 0 || index > tabReport.TabPages.Count - 1)
            {
                tabReport.TabPages.Add(page);
            }
            else
            {
                tabReport.TabPages.Insert(index, page);
            }

            //如果是分组，创建分组弹出菜单
            if (BlockIsGroup(blockId))
            {
                CreateGroupMenu(blockId);
            }

            return page;
        }

        // 切换到指定板块
        private void BlockSwitch(string blockLabel, string blockId)
        {
            if (string.IsNullOrEmpty(blockId))
                return;

            currentBlockId = blockId;

            BlockStockDataRefrech();

            TabPage page = null;
            foreach (TabPage p in tabReport.TabPages)
            {
                string tabBlockId = Convert.ToString(p.Tag);
                if (tabBlockId == blockId)
                {
                    page = p;
                    break;
                }
            }
            if (page == null)
            {
                foreach (TabPage p in tabReport.TabPages)
                {
                    string tabBlockId = Convert.ToString(p.Tag);
                    if (string.IsNullOrEmpty(tabBlockId))
                        continue;

                    if (BlockIsGroup(tabBlockId) && blockId.StartsWith(tabBlockId))
                    {
                        page = p;
                        break;
                    }
                }
            }
            if (page == null)
            {
                string blockLabelNew = blockLabel;
                string blockIdNew = blockId;
                if (StockBlockGroupRegular.Instance.ContainsKey(blockId))
                {
                    blockLabelNew = StockBlockGroupRegular.Instance[blockId].GroupName;
                    blockIdNew = blockLabelNew + ".";
                }
                if (StockBlockGroupCustom.Instance.ContainsKey(blockId))
                {
                    blockLabelNew = StockBlockGroupCustom.Instance[blockId].GroupName;
                    blockIdNew = blockLabelNew + ".";
                }
                if (StockBlockGroupClass.Instance.ContainsKey(blockId))
                {
                    blockLabelNew = StockBlockGroupClass.Instance[blockId].GroupName;
                    blockIdNew = blockLabelNew + ".";
                }

                page = CreateReportTab(blockLabelNew, blockIdNew, -1);
                BlockTabFit();

                StockTab tab = new StockTab();
                tab.Name = blockLabelNew;
                tab.BlockId = blockIdNew;
                StockTabContainer.Instance.Add(tab);
            }

            suppressSwitchWhentIndexChanging = false;
            tabReport.SelectedTab = page;
            suppressSwitchWhentIndexChanging = true;

            lblBlock.Visible = true;
            if (BlockIsGroup(page.Tag) && !currentBlockId.StartsWith(StockBlockGroupClass.BLOCK_GROUP_ID))
            {
                lblBlock.Text = "板块： " + Regex.Replace(currentBlockId, @"^(.+)\.(.+)$", @"$2$1"); //［］
            }
            else
            {
                lblBlock.Text = "板块： " + Regex.Replace(currentBlockId, @"^(.+)\.(.+)$", @"$2");
            }

            SendMessage(FormParent, new FormNotifyMessage("Main.ChangeBlock", currentBlockId));
        }

        // 更新列表数据
        private void BlockStockDataRefrech()
        {
            if (string.IsNullOrEmpty(currentBlockId))
                return;

            string[] blockFilterParts = currentBlockId.Split(new char[] { '.' }, StringSplitOptions.None);
            if (blockFilterParts.Length != 2)
                return;

            if (StockContainer.Instance.Count <= 0)
                return;

            // 获取板块列表
            IEnumerable<Stock> stockList = null;
            switch (blockFilterParts[0])
            {
                case StockBlockGroupClass.BLOCK_GROUP_NAME:
                    if (StockBlockGroupClass.Instance.ContainsKey(currentBlockId))
                    {
                        stockList = StockBlockGroupClass.Instance[currentBlockId].Values;
                    }
                    break;

                case StockBlockGroupCustom.BLOCK_GROUP_NAME:
                    if (StockBlockGroupCustom.Instance.ContainsKey(currentBlockId))
                    {
                        stockList = StockBlockGroupCustom.Instance[currentBlockId].Values;
                    }
                    break;

                default:
                    if (StockBlockGroupRegular.Instance.ContainsKey(currentBlockId))
                    {
                        stockList = StockBlockGroupRegular.Instance[currentBlockId].Values;
                    }
                    break;
            }

            if (stockList == null)
                stockList = new List<Stock>();

            // 进行排序
            if (gridReport.SortNeededColumn != null && !string.IsNullOrEmpty(gridReport.SortNeededColumn.DataPropertyName))
            {
                PropertyInfo pi = typeof(Stock).GetProperty(gridReport.SortNeededColumn.DataPropertyName);
                if (pi != null)
                {
                    if (gridReport.SortNeededOrder == SortOrder.Ascending)
                    {
                        stockList = stockList.OrderBy(r => pi.GetValue(r, null));
                    }
                    if (gridReport.SortNeededOrder == SortOrder.Descending)
                    {
                        stockList = stockList.OrderByDescending(r => pi.GetValue(r, null));
                    }
                }
            }

            // 更新数据
            gridReport.DataSource = stockList.ToList();
        }

        // 更新标签数据
        private void BlockDataRefrech()
        {
            foreach (TabPage page in tabReport.TabPages)
            {
                string blockId = Convert.ToString(page.Tag);
                if (string.IsNullOrEmpty(blockId))
                    continue;

                if (blockId.StartsWith(StockBlockGroupCustom.BLOCK_GROUP_ID) && Regex.IsMatch(blockId, @"^(.+)\.(.+)$"))
                {
                    if (!StockBlockGroupCustom.Instance.ContainsKey(blockId))     // 板块标签已被删除
                    {
                        if (currentBlockId == blockId)
                        {
                            BlockTabSelectFirst();
                        }

                        tabReport.TabPages.Remove(page);
                        BlockTabFit();

                        foreach (StockTab tab in StockTabContainer.Instance)
                        {
                            if (tab.BlockId == blockId)
                            {
                                StockTabContainer.Instance.Remove(tab);
                                break;
                            }
                        }

                        continue;
                    }
                    else // 板块标签已改名
                    {
                        page.Text = StockBlockGroupCustom.Instance[blockId].Name;
                    }
                }

                // 重建板块分组的弹出菜单
                if (blockId == StockBlockGroupCustom.BLOCK_GROUP_ID)
                {
                    CreateGroupMenu(blockId);
                }
            }

            if (!string.IsNullOrEmpty(currentBlockId) && currentBlockId.StartsWith(StockBlockGroupCustom.BLOCK_GROUP_ID) && !StockBlockGroupCustom.Instance.ContainsKey(currentBlockId))     // 当前板块已被删除
            {
                BlockTabSelectFirst();
            }
        }

        // 重建标签数据
        private void BlockTabDataRefresh()
        {
            bool fitTab = false;
            bool reselectTab = false;

            // 删除Tab中多余的标签
            foreach (TabPage page in tabReport.TabPages)
            {
                bool exist = false;
                foreach (StockTab tab in StockTabContainer.Instance)
                {
                    if (Convert.ToString(page.Tag) == tab.BlockId)
                    {
                        exist = true;
                        break;
                    }
                }
                if (!exist)
                {
                    if (currentBlockId == Convert.ToString(page.Tag))
                    {
                        reselectTab = true;
                    }

                    tabReport.TabPages.Remove(page);
                    fitTab = true;
                }
            }

            // 添加Tab中不存在的标签
            int index = 0;
            foreach (StockTab tab in StockTabContainer.Instance)
            {
                bool exist = false;
                foreach (TabPage page in tabReport.TabPages)
                {
                    if (Convert.ToString(page.Tag) == tab.BlockId)
                    {
                        exist = true;
                        break;
                    }
                }
                if (!exist)
                {
                    CreateReportTab(tab.Name, tab.BlockId, index);
                    fitTab = true;
                }

                index++;
            }

            // 如果顺序不合适，调整顺序
            for (int i = 0; i < StockTabContainer.Instance.Count; i++)
            {
                // 找到标签
                int j = 0;
                for (j = 0; j < tabReport.TabPages.Count; j++)
                {
                    if (Convert.ToString(tabReport.TabPages[j].Tag) == StockTabContainer.Instance[i].BlockId)
                    {
                        break;
                    }
                }

                if (j != i)
                {
                    suppressSelectingWhenIndexChanged = true;
                    TabPage pageSelect = tabReport.SelectedTab;
                    TabPage pagej = tabReport.TabPages[j];
                    tabReport.TabPages.RemoveAt(j);
                    tabReport.TabPages.Insert(i, pagej);
                    tabReport.SelectedTab = pageSelect;
                    suppressSelectingWhenIndexChanged = false;
                }
            }

            if (reselectTab)
            {
                BlockTabSelectFirst();
            }

            // 调节Tab控件宽度
            if (fitTab)
            {
                BlockTabFit();
            }
        }

        private void BlockTabSelectFirst()
        {
            if (tabReport.TabPages.Count <= 0)
                return;

            string blockLabel = string.Empty;
            string blockId = string.Empty;
            foreach (TabPage page in tabReport.TabPages)
            {
                if (!BlockIsGroup(page.Tag))
                {
                    blockLabel = page.Text;
                    blockId = Convert.ToString(page.Tag);
                    break;
                }
            }
            if (string.IsNullOrEmpty(blockId))
            {
                blockLabel = tabReport.TabPages[0].Text;
                blockId = Convert.ToString(tabReport.TabPages[0].Tag);
                if (groupMenu.ContainsKey(blockId) && groupMenu[blockId].Items.Count > 0)
                {
                    blockLabel = groupMenu[blockId].Items[0].Text;
                    blockId = Convert.ToString(groupMenu[blockId].Items[0].Tag);
                }
            }
            if (!string.IsNullOrEmpty(blockId))
            {
                BlockSwitch(blockLabel, blockId);
            }
        }

        private bool BlockIsGroup(object blockIdObj)
        {
            string blockId = Convert.ToString(blockIdObj);

            if (string.IsNullOrEmpty(blockId))
                return false;

            return blockId.EndsWith(".");
        }

        private void cmdOpen_Click(object sender, EventArgs e)
        {
            SendKeys.Send("{Enter}");
        }

        private void cmdF10_Click(object sender, EventArgs e)
        {
            SendKeys.Send("{F10}");
        }

        private void cmdBlock_Click(object sender, EventArgs e)
        {
            SendKeys.Send("^r");
        }

        private void cmdBlockAdd_Click(object sender, EventArgs e)
        {
            SendKeys.Send("^z");
        }

        private void cmdBlockZXG_Click(object sender, EventArgs e)
        {
            SendKeys.Send("%z");
        }

        private void cmdBlockDelete_Click(object sender, EventArgs e)
        {
            SendKeys.Send("{DELETE}");
        }

        private void cmdBlockSetup_Click(object sender, EventArgs e)
        {
            SendKeys.Send("^b");
        }

        private void lblBlock_DoubleClick(object sender, EventArgs e)
        {
            SendKeys.Send("^b");
        }
    }
}
